#include <stdio.h>
#include <string.h>        // 若需要 memset
#include "cmsis_os2.h"     // CMSIS-RTOS v2 头文件

/* 等待的事件类型 */
#define EVENT_WAIT 0x00000001

/* 全局事件标志对象ID */
static osEventFlagsId_t g_exampleEvent;

/* 线程ID */
static osThreadId_t g_testTaskId;

/* 任务入口函数 (原 Example_Event) */
static void Example_Event(void *argument)
{
    (void)argument; // 若不使用该参数可以忽略

    printf("Example_Event wait event 0x%x \n", EVENT_WAIT);

    // 等待指定事件标志（所有位满足，即与操作），超时100个Tick
    // 返回值若包含 EVENT_WAIT，则说明等待到该事件
    uint32_t event = osEventFlagsWait(g_exampleEvent,
                                      EVENT_WAIT,
                                      osFlagsWaitAll,
                                      100); // 超时100 ticks

    if ((event & 0x80000000U) != 0) {
        // 若最高位为1，表示出错或超时，可用下面这种判断方式
        printf("Example_Event, read event timeout or error\n");
    } else {
        // 如果正常返回，event 中会包含已设置的标志位
        if ((event & EVENT_WAIT) == EVENT_WAIT) {
            printf("Example_Event, read event : 0x%x\n", event);
        } else {
            printf("Example_Event, read event timeout\n");
        }
    }

    // 线程函数如果需要结束，可以调用 osThreadExit()
    osThreadExit();
}

/* 另一个任务入口函数 (原 Example_TaskEntry) */
int Example_TaskEntry(void)
{
    // 1. 初始化CMSIS-RTOS内核(若主函数未初始化)
    //    这里仅演示，如果你的系统启动时已经调用了 osKernelInitialize/osKernelStart
    //    就不需要重复初始化
    if (osKernelGetState() == osKernelInactive) {
        osKernelInitialize();
    }

    // 2. 创建事件标志
    g_exampleEvent = osEventFlagsNew(NULL);
    if (g_exampleEvent == NULL) {
        printf("init event failed.\n");
        return -1;
    }

    // 3. 创建任务(线程)
    osThreadAttr_t attr;
    memset(&attr, 0, sizeof(osThreadAttr_t));   // 若使用 securec，可改为 memset_s
    attr.name = "EventTsk1";
    // 根据实际需要设置栈大小、优先级
    // 注意：CMSIS-RTOS v2 中优先级通常用 osPriorityNormal、osPriorityHigh 等枚举值
    //       或者在某些实现里可用 osPriorityNormal + n 方式
    attr.priority = osPriorityNormal;  
    attr.stack_size = 1024U;  // 根据需要设定栈大小

    g_testTaskId = osThreadNew(Example_Event, NULL, &attr);
    if (g_testTaskId == NULL) {
        printf("task create failed.\n");
        return -1;
    }

    // 如果此时系统尚未启动调度，则需要启动RTOS内核
    if (osKernelGetState() == osKernelReady) {
        osKernelStart();
    }

    // 4. 写事件标志
    printf("Example_TaskEntry write event.\n");
    uint32_t ret = osEventFlagsSet(g_exampleEvent, EVENT_WAIT);
    if ((int32_t)ret < 0) {
        printf("event write failed.\n");
        return -1;
    }

    // 5. 读取当前事件标志（仅做打印）
    uint32_t mask = osEventFlagsGet(g_exampleEvent);
    printf("EventMask: 0x%x\n", mask);

    // 6. 清除事件标志
    ret = osEventFlagsClear(g_exampleEvent, mask);
    printf("EventMask after clear: 0x%x\n", osEventFlagsGet(g_exampleEvent));

    // 7. 删除线程(若需要在此主动结束 Example_Event 线程)
    //    如果 Example_Event 内部已调用 osThreadExit()，则也可不强制终止
    if (osThreadTerminate(g_testTaskId) != osOK) {
        printf("task delete failed.\n");
        return -1;
    }

    // 8. 删除事件标志对象(若后续不再需要)
    if (osEventFlagsDelete(g_exampleEvent) != osOK) {
        printf("event delete failed.\n");
        return -1;
    }

    return 0;
}
